{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Notebook for Serving The Trained Model for Classifying TinyImageNet. Notebook (4/4) in the End-to-End Scalable Deep Learning Pipeline on Hops.\n",
    "\n",
    "\n",
    "This notebook will send inference requests to a model serving instance that was exported by notebook number three ([Notebook number three](./Step3_Distributed_Training.ipynb)). This assumes that you have created a model serving instance of the model by using the hopsworks UI. You can find documentation on how to do this [here](https://hops.readthedocs.io/en/0.9/hopsml/model_serving.html)\n",
    "\n",
    "![step4.png](../images/step4.png)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "from hops import util\n",
    "from hops import hdfs\n",
    "from hops import constants\n",
    "import os\n",
    "from hops import featurestore\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Constants"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "PROJECT_ID = 21139\n",
    "MODEL = \"tinyimagenet_resnet50\"\n",
    "PROJECT = hdfs.project_name()\n",
    "INFERENCE_URL = (\"/\" + \n",
    "                 constants.REST_CONFIG.HOPSWORKS_REST_RESOURCE + \n",
    "                 \"/project/\" + \n",
    "                 str(PROJECT_ID) + \n",
    "                 \"/inference/models/\" + \n",
    "                 MODEL + \n",
    "                 \":predict\"\n",
    "                )\n",
    "SERVER = \"\"\n",
    "WORK_DIR = \"\"\n",
    "CONCURRENCY = \"\"\n",
    "NUM_TESTS = \"\"\n",
    "TEST_DATASET = \"test_dataset_tinyimagenet\"\n",
    "HEIGHT = 64\n",
    "WIDTH = 64\n",
    "CHANNELS = 3\n",
    "BATCH_SIZE = 100\n",
    "SHUFFLE_BUFFER_SIZE = 1000\n",
    "INPUT_SHAPE = 12288\n",
    "NUM_CLASSES = 200"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_tf_dataset():\n",
    "    \"\"\"\n",
    "    Creates a Tensorflow Dataset from TFRecords on HopsFS stored in the feature store.\n",
    "    \n",
    "    Returns:\n",
    "           Tensorflow dataset\n",
    "    \"\"\"\n",
    "    \n",
    "    # Get Path and Schema from feature store metadata\n",
    "    tf_record_schema = featurestore.get_training_dataset_tf_record_schema(TEST_DATASET)\n",
    "    dataset_dir = featurestore.get_training_dataset_path(TEST_DATASET)\n",
    "    \n",
    "    input_files = tf.gfile.Glob(dataset_dir + \"/part-r-*\")\n",
    "    dataset = tf.data.TFRecordDataset(input_files)\n",
    "\n",
    "    def decode(example_proto):\n",
    "        example = tf.parse_single_example(example_proto, tf_record_schema)\n",
    "        image_flat = example[\"image\"]\n",
    "        image = tf.reshape(image_flat, (HEIGHT,WIDTH,CHANNELS))\n",
    "        return image\n",
    "\n",
    "    dataset = dataset.map(decode)\n",
    "    return dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "def do_inference():\n",
    "    with tf.Session() as sess:\n",
    "        dataset = get_tf_dataset()\n",
    "        dataset_iter = dataset.make_one_shot_iterator()\n",
    "        for i in range(5):\n",
    "            x = sess.run(dataset_iter.get_next())\n",
    "            print(\"feature shape: {}\".format(x.shape))\n",
    "            request_data={}\n",
    "            request_data['instances'] = x\n",
    "            headers={}\n",
    "            # TODO this will work in hopsworks 0.10.0 when JWT is enabled\n",
    "            #headers[constants.HTTP_CONFIG.HTTP_AUTHORIZATION] = \"Bearer \" + util.get_jwt()\n",
    "            #r = requests.post(INFERENCE_URL, headers=headers, data=json.dumps(request_data), verify=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "#do_inference()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "PySpark",
   "language": "",
   "name": "pysparkkernel"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "python",
    "version": 2
   },
   "mimetype": "text/x-python",
   "name": "pyspark",
   "pygments_lexer": "python2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}